package org.jheuristics.ga.operators.selectors;

import java.util.Comparator;

import org.epanetgrid.otimizacao.log.AGLogger;
import org.epanetgrid.otimizacao.util.OtimizacaoUtil;
import org.jheuristics.Individual;
import org.jheuristics.ga.GAConfig;
import org.jheuristics.ga.GAStatus;
import org.jheuristics.util.RandomGenerator;


/**
 * TODO
 * 
 * @author Marcell Manfrin, marcell at ourgrid.org, 2005
 */
public class DefaultTournamentSelection extends AbstractTournamentSelection {
	private int tournamentSize;

	/**
	 * TODO
	 */
	public DefaultTournamentSelection() {
		super();
		setTournamentSize(2);
	}

	/**
	 * TODO
	 *
	 * @param comparator
	 */
	public DefaultTournamentSelection(Comparator comparator) {
		super(comparator);
	}

	/**
	 * TODO
	 * 
	 * @param tournamentSize
	 */
	public DefaultTournamentSelection(int tournamentSize) {
		setTournamentSize(tournamentSize);
	}

	/**
	 * TODO
	 * 
	 * @param tournamentSize
	 */
	public DefaultTournamentSelection(Comparator comparator, int tournamentSize) {
		setComparator(comparator);
		setTournamentSize(tournamentSize);
	}

	/**
	 * TODO
	 * 
	 * @param individuals
	 * @param status
	 * @param config
	 * @return
	 * @see org.jheuristics.ga.operators.selectors.AbstractTournamentSelection#select(org.jheuristics.Individual[],
	 * org.jheuristics.ga.GAStatus, org.jheuristics.ga.GAConfig)
	 */
	protected Individual select(Individual[] individuals, GAStatus status, GAConfig config) {
		RandomGenerator random = config.getRandomGenerator();
		Individual result = individuals[random.nextInt(individuals.length)];
		Individual perdedor = null;
		for (int i = 0; i < getTournamentSize() - 1; i++) {
			Individual selected = individuals[random.nextInt(individuals.length)];
			perdedor = selected;
			if (null == getComparator()) {
				if (result.compareTo(selected) < 0) {
					perdedor = result;
					result = selected;
				}
			} else {
				if (getComparator().compare(result, selected) < 0) {
					perdedor = result;
					result = selected;
				}
			}
		}
		
		
		StringBuffer buf = new StringBuffer();
		buf.append("\n");
		buf.append("Indivíduos selecionados para torneio: ");
		buf.append("\n");
		buf.append(OtimizacaoUtil.format(perdedor));
		buf.append("\n");
		buf.append(OtimizacaoUtil.format(result));
		buf.append("\n");
		buf.append("Indivíduo Campeão: \n");
		buf.append(OtimizacaoUtil.format(result));
		buf.append("\n");
		AGLogger.getInstance().debug(buf);
		return result;
	}

	/**
	 * TODO
	 * 
	 * @return
	 */
	public int getTournamentSize() {
		return tournamentSize;
	}

	/**
	 * TODO
	 * 
	 * @param tournamentSize
	 */
	public void setTournamentSize(int tournamentSize) {
		if (0 >= tournamentSize) {
			// TODO: ERROR MSG
			throw new IllegalArgumentException();
		}
		this.tournamentSize = tournamentSize;
	}

}
